%include
:- lib(ic).

test(Arg1,Arg2,Result2):-
allPathSumSum(Arg1,NState1),
singlePathSumCalculate(NState1,Arg2,Result2).

% constructor with side effect
allPathSumSum(Arg, NState) :-
% Variables
	NState = [NNumber],
	Arg = [N],
% Domains
	[NNumber] :: 1 .. 128,
	[N] :: 1 .. 128,
% Precondition
	N #> 0,
% Postcondition
	NNumber #= N,
% Invariant
	NNumber #> 0,
% Solving
	indomain(NNumber),
	indomain(N).

% method without side effect
singlePathSumCalculate(OState, Arg, Result) :-
% Domains
%% states
	[ONumber] :: 1..128,
	[NNumber] :: 1 .. 128,
%% parameter
	[Accumulator] :: 1 .. 128,
% Variables
%% states
	OState = [ONumber],
	NState = [NNumber],
%% parameter
	Arg = [Accumulator],
% Invariant
	NNumber #= ONumber,
	NNumber #> 0,	
% Postcondition
	neg(Accumulator #= 1),
	Previous #= Accumulator -1,
	calculate(NState, [Previous],[Result1]),
	Result #= Accumulator + Result1,
% Solving
	indomain(ONumber),
	indomain(NNumber),
	indomain(Accumulator).

calculate([ONumber], [Accumulator], [Result]) :-
% Postcondition
	Accumulator #= 1,
	Result = 1,
% State Update
	NNumber #= ONumber,
% Invariant
	NNumber #> 0.

calculate([ONumber], [Accumulator], [Result], [NNumber]) :-
% Postcondition
	neg(Accumulator #= 1),
	Previous #= Accumulator - 1,
	calculate([ONumber],[Previous],[Result1],[NNumber]),
	Result #= Accumulator + Result1,
% State Update
	NNumber #= ONumber,
% Invariant
	NNumber #> 0.
